﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autofac;
using System.Reflection;
using Learn.Net8.IService;
using Learn.Net8.Service;
using Learn.Net8.Repository;
using Autofac.Extras.DynamicProxy;

namespace Learn.Net8.Extension.ServiceExtensions
{
    // 继承 Autofac.Module 类
    // Autofac.Module 是 Autofac 的模块化注册类
    public class AutofacModuleRegister : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            // 记录上下文当前目录，生成在 Bin 同文件夹下
            var basePath = AppContext.BaseDirectory;
            // 记录服务层目录
            var servicesDllFile = Path.Combine(basePath, "Learn.Net8.Service.dll");
            // 记录仓储层目录
            var repositoryDllFile = Path.Combine(basePath, "Learn.Net8.Repository.dll");

            // 记录 AOP 切面类
            var aopTypes = new List<Type>() { typeof(ServiceAOP) };
            builder.RegisterType<ServiceAOP>();

            // 设置注册模式
            builder.RegisterGeneric(typeof(BaseRepository<>))
                .As(typeof(IBaseRepository<>))
                .InstancePerDependency();

            builder.RegisterGeneric(typeof(BaseService<,>))
                .As(typeof(IBaseService<,>))
                .InstancePerDependency()
                .EnableInterfaceInterceptors()
                .InterceptedBy(aopTypes.ToArray()); // 注册服务

            // 通过反射获取 Service.dll 程序集服务
            var assemblyServices = Assembly.LoadFrom(servicesDllFile);
            // 注册：
            //  限定以 Service 结尾的类才会被注册
            //  对其实现的所有接口注册当前类为实现类
            //  设置属性自动注入
            //  设置生命周期为每次请求创建一个新的实例
            builder.RegisterAssemblyTypes(assemblyServices)
                                .Where(t => t.Name.EndsWith("Service"))
                                .AsImplementedInterfaces()
                                .InstancePerLifetimeScope()
                                .PropertiesAutowired()
                                .EnableInterfaceInterceptors()
                                .InterceptedBy(aopTypes.ToArray());

            // 同样设置仓储层
            var assemblyRepository = Assembly.LoadFrom(repositoryDllFile);
            builder.RegisterAssemblyTypes(assemblyRepository)
                                .Where(t => t.Name.EndsWith("Repository"))
                                .AsImplementedInterfaces()
                                .PropertiesAutowired()
                                .InstancePerLifetimeScope();
        }
    }
}
